package org.come.until;

import java.io.File;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;

public class MusicPlayer_3 {
	private String musicPath; //音频文件
	private volatile boolean run = true;  //记录音频是否播放
	private Thread mainThread;   //播放音频的任务线程
	private AudioInputStream audioStream;//音频流
	private AudioFormat audioFormat;//音频格式
	private SourceDataLine sourceDataLine;
	MusicPlayer_3 musicPlayer_3;//播放
	public MusicPlayer_3(String musicPath) {
		musicPlayer_3=this;
		this.musicPath = musicPath;
		prefetch();
	}
	//数据准备
	private void prefetch(){
		try{
			File file = new File(musicPath);
			// 取得文件输入流
			audioStream = AudioSystem.getAudioInputStream(file);
			audioFormat = audioStream.getFormat();
			// 转换mp3文件编码
			if (audioFormat.getEncoding() != AudioFormat.Encoding.PCM_SIGNED) {
				audioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
						audioFormat.getSampleRate(), 16,
						audioFormat.getChannels(),
						audioFormat.getChannels() * 2,
						audioFormat.getSampleRate(), false);
				audioStream = AudioSystem.getAudioInputStream(audioFormat,audioStream);
			}
			// 打开输出设备
			DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, audioFormat,AudioSystem.NOT_SPECIFIED);
			sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
			sourceDataLine.open(audioFormat);
			sourceDataLine.start();
		}catch(Exception ex){
			System.err.println(musicPath);
			Music.kz1=false;
			Music.kz2=false;
			Music.beijing(false);
			Music.yinxiao(false);
			System.err.println("音乐报错");
//          ex.printStackTrace();
		}
	}
	//析构函数:关闭音频读取流和数据行
	@Override
	protected void finalize() throws Throwable{
		super.finalize();
		sourceDataLine.drain();
		sourceDataLine.close();
		audioStream.close();
	}
	//播放音频:通过loop参数设置是否循环播放
	private void playMusic(boolean loop) throws InterruptedException {
		try {
			if (loop) {
				while (true) {
					playMusic();
				}
			} else {
				playMusic();
				// 清空数据行并关闭
				sourceDataLine.drain();
				sourceDataLine.close();
				audioStream.close();
			}
		} catch (Exception ex) {
			// ex.printStackTrace();
		}
	}

	private void playMusic() throws Exception {
		synchronized (this) {
			run = true;
		}
		File file = new File(musicPath);
		// 取得文件输入流
		audioStream = AudioSystem.getAudioInputStream(file);
		audioFormat = audioStream.getFormat();
		// 转换mp3文件编码
		if (audioFormat.getEncoding() != AudioFormat.Encoding.PCM_SIGNED) {
			audioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
					audioFormat.getSampleRate(), 16, audioFormat.getChannels(),
					audioFormat.getChannels() * 2, audioFormat.getSampleRate(),
					false);
			audioStream = AudioSystem.getAudioInputStream(audioFormat,audioStream);
		}
		// 通过数据行读取音频数据流，发送到混音器;
		// 数据流传输过程：AudioInputStream -> SourceDataLine;
		int count;
		byte tempBuff[] = new byte[1024];
		while ((count = audioStream.read(tempBuff, 0, tempBuff.length)) != -1) {
			synchronized (this) {
				while (!run) {
                    wait();
                }
			}
			sourceDataLine.write(tempBuff, 0, count);
		}
	}
	//暂停播放音频
	private void stopMusic(){
		synchronized(this){
			run = false;
			notifyAll();
		}
	}
	//继续播放音乐
	private void continueMusic() {
		synchronized (this) {
			run = true;
			notifyAll();
		}
	}
	//外部调用控制方法:生成音频主线程；
	public void start(final boolean loop){
		mainThread = new Thread(new Runnable(){
			@Override
			public void run(){
				try {
					playMusic(loop);
					if (!loop) {
						Music.players.remove(musicPlayer_3);
					}

				} catch (InterruptedException e) {
					Music.players.remove(musicPlayer_3);
//                  e.printStackTrace();
				}
			}
		});
		mainThread.start();
	}
	//外部调用控制方法：暂停音频线程
	public void stop() {
		new Thread(new Runnable() {
			@Override
			public void run() {
				stopMusic();
			}
		}).start();
	}
	//外部调用控制方法：继续音频线程
	public void continues() {
		new Thread(new Runnable() {
			@Override
			public void run() {
				continueMusic();
			}
		}).start();
	}
	public String getMusicPath() {
		return musicPath;
	}
	public void setMusicPath(String musicPath) {
		this.musicPath = musicPath;
	}
	public Thread getMainThread() {
		return mainThread;
	}
	public void setMainThread(Thread mainThread) {
		this.mainThread = mainThread;
	}

	public SourceDataLine getSourceDataLine() {
		return this.sourceDataLine;
	}
}  